package com.llbnk.srb.core.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.llbnk.srb.core.mapper.DictMapper;
import com.llbnk.srb.core.pojo.dto.ExcelDictDTO;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author shkstart
 * @create 2022-04-10 9:38
 */
/**
 * excel导入后端流程：
 * 前端调用后端import接口，在batchImport实现，在方法中拿到file文件拿到inputStream
 * 然后传递给Service层做业务（调用的还是DictServiceImpl，DictService的实现类）
 * 在service（DictServiceImpl）中创建了一个对象监听器ExcelDictDTOListener()
 * 通过监听器创建我们进行了Excel的读，通过doRead()去执行读
 * 并希望自动的将读出来的数据封装到ExcelDictDTO里面
 * 具体的封装过程是在ExcelDictDTOListener监听器中实现的，重写方法调用mapper层完成数据的存储
 */
@Slf4j
@NoArgsConstructor
public class ExcelDictDTOListener extends AnalysisEventListener<ExcelDictDTO> {

    private DictMapper dictMapper;

    //存放数据链表我们希望每隔n个数据往数据库中写一次，而不是每一次invoke方法都写
    private  List<ExcelDictDTO> list=new ArrayList<ExcelDictDTO>();

    //每个5条记录批量存储一次数据
    private static final int BATCH_COUNT = 5;

    public ExcelDictDTOListener(DictMapper dictMapper) {
        this.dictMapper = dictMapper;
    }

    @Override
    public void invoke(ExcelDictDTO data, AnalysisContext analysisContext) {
    //data就是excel表中的一条记录 它会将这个记录封装成ExcelStudentDTO对象
        // 然后{}是占位符 打印的就是这条记录的数据
        log.info("解析到一条记录: {}",data);
        //将数据存入数据列表
        list.add(data);
        if(list.size()>=BATCH_COUNT){
            //调用mapper层的save方法
            saveData();
            list.clear();
        }
        //这只能处理BATCH_COUNT整数倍的数据，所以多出的数据不满BATCH_COUNT需要在doAfterAllAnalysed中处理
    }

    private void saveData() {
        log.info("{}条数据被存储到数据库......",list.size());
        //调用mapper层的批量save方法:save list对象
        //TODO
        dictMapper.insertBatch(list);
        log.info("{}条数被成功存储到数据库中!",list.size());
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //invoke只能处理BATCH_COUNT整数倍的数据，所以多出的数据不满BATCH_COUNT需要在doAfterAllAnalysed中处理
        saveData();
        //都打印完成后才会调用
        log.info("说有数据解析完成！");
    }

}
